/**
 * 动态路由处理
 * 根据接口返回的菜单列表注册动态路由
 * 
 * 修复日期: 2025/4/24
 * 修复内容: 解决同名路由注册问题，确保当有多个同名路由但路径不同时，它们都能被正确注册
 */
import type { Router, RouteRecordRaw } from 'vue-router'
import type { MenuListType } from '../../types/menu'
import { saveIframeRoutes, handleComponentMapping } from '../../utils/menu'
import AppLayout from '../../components/layout/AppLayout.vue'

/**
 * 动态导入 views 目录下所有 .vue 组件
 */
const modules: Record<string, () => Promise<any>> = import.meta.glob('../../views/**/*.vue')

// 也导入components目录下的组件，确保DashboardPage等组件可用
const componentModules: Record<string, () => Promise<any>> = import.meta.glob('../../components/**/*.vue')

/**
 * 根据组件路径动态加载组件
 * @param componentPath 组件路径（不包含 @/views 前缀和 .vue 后缀）
 * @param routeName 当前路由名称（用于错误提示）
 * @returns 组件加载函数
 */
function loadComponent(componentPath: string | undefined, routeName: string): () => Promise<any> {
  if (!componentPath) {
    console.error(`路由 ${routeName} 缺少组件路径`)
    return () => import('../../views/error/404.vue')
  }

  // 处理Layout特殊情况
  const mappedPath = handleComponentMapping(componentPath)
  
  // 检查是否是相对路径（不以/或@开头）
  const isRelativePath = !mappedPath.startsWith('/') && !mappedPath.startsWith('@')
  
  // 构建完整的views路径
  const viewsPath = `../../views/${mappedPath}.vue`
  console.log(`尝试加载组件: ${viewsPath}`)
  
  // 查找匹配的模块
  let moduleFound = modules[viewsPath]
  
  // 如果未找到，可能是因为映射路径问题，尝试其他可能的路径格式
  if (!moduleFound && isRelativePath) {
    // 尝试常见路径格式
    const possibleViewPaths = [
      `../../views/${mappedPath}/index.vue`,      // 例如：@/views/document/shared/index.vue
      `../../views/${mappedPath}.vue`,            // 例如：@/views/document/shared.vue
      `../../views/${mappedPath}/main.vue`,       // 例如：@/views/document/shared/main.vue
      `../../views/${mappedPath.replace(/\/index$/, '')}/index.vue` // 处理可能的重复index
    ]
    
    // 特殊处理带连字符的路径，如image/shared-images -> image/shared/index.vue
    if (mappedPath.includes('-')) {
      const pathParts = mappedPath.split('/')
      const lastPart = pathParts[pathParts.length - 1]
      
      if (lastPart.includes('-')) {
        // 提取连字符前的部分作为目录名
        const dirName = lastPart.split('-')[0]
        const parentPath = pathParts.slice(0, -1).join('/')
        const convertedPath = parentPath ? `${parentPath}/${dirName}/index.vue` : `${dirName}/index.vue`
        possibleViewPaths.push(`../../views/${convertedPath}`)
        
        console.log(`尝试处理连字符路径: ${mappedPath} -> ../../views/${convertedPath}`)
      }
    }
    
    // 检查所有可能的路径
    for (const path of possibleViewPaths) {
      if (modules[path]) {
        moduleFound = modules[path]
        console.log(`找到匹配组件: ${path}`)
        break
      }
    }
  }
  
  // 如果在views目录下没找到，尝试在components目录查找
  if (!moduleFound) {
    console.log(`在views目录下未找到组件：${routeName}，尝试在components目录下查找`)
    
    // 尝试在components目录中查找
    const possibleComponentPaths = [
      `../../components/${mappedPath}.vue`,
      `../../components/${mappedPath}/index.vue`,
      `../../components/${mappedPath}/main.vue`
    ]
    
    // 检查所有可能的组件路径
    for (const path of possibleComponentPaths) {
      if (componentModules[path]) {
        moduleFound = componentModules[path]
        console.log(`在components目录下找到组件：${path}`)
        break
      }
    }
    
    // 如果仍未找到，输出错误并返回404页面
    if (!moduleFound) {
      console.error(`未找到组件：${routeName} (${mappedPath})，已尝试多种路径格式`)
      // 定义可能的视图路径列表（如果上面没有定义）
      const possibleViewPaths = [
        `../../views/${mappedPath}/index.vue`,
        `../../views/${mappedPath}.vue`,
        `../../views/${mappedPath}/main.vue`,
        `../../views/${mappedPath.replace(/\/index$/, '')}/index.vue`
      ]
      console.log(`所有尝试的路径：`, [...possibleViewPaths, ...possibleComponentPaths])
      return () => import('../../views/error/404.vue')
    }
  }
  
  return moduleFound
}

/**
 * 注册异步路由
 * 将接口返回的菜单列表转换为 Vue Router 路由配置，并添加到传入的 router 实例中
 * 
 * 说明: 此函数会处理同名路由问题，在检测到同名但不同路径的路由时，会自动为路由名称添加前缀
 * 例如: 系统管理下的"操作日志"和个人中心下的"操作日志"，会被修改为"system-操作日志"和"profile-操作日志"
 * 
 * @param router Vue Router 实例
 * @param menuList 接口返回的菜单列表
 */
export function registerAsyncRoutes(router: Router, menuList: MenuListType[]): void {
  // 打印所有可用的模块路径，帮助调试
  console.log('%c ---------- 可用的视图组件路径 ----------', 'background:#E6A23C; color:white; padding: 4px; border-radius: 4px;');
  const availableModules = Object.keys(modules).sort();
  console.log(`共有 ${availableModules.length} 个视图组件`);
  // 打印前10个路径作为示例
  availableModules.slice(0, 10).forEach(path => console.log(`- ${path}`));
  
  console.log('%c ---------- 可用的组件路径 ----------', 'background:#E6A23C; color:white; padding: 4px; border-radius: 4px;');
  const availableComponents = Object.keys(componentModules).sort();
  console.log(`共有 ${availableComponents.length} 个通用组件`);
  // 打印前10个路径作为示例
  availableComponents.slice(0, 10).forEach(path => console.log(`- ${path}`));

  // 先确保AppLayout路由已注册
  if (!router.hasRoute('AppLayout')) {
    router.addRoute({
      path: '/dashboard',
      name: 'AppLayout',
      component: AppLayout,
      meta: { requiresAuth: true },
      children: []
    })
  }

  // 用于局部收集iframe类型路由
  const iframeRoutes: MenuListType[] = []
  
  // 保存路由路径和组件路径的映射，用于后面打印时查找
  const routeComponentMapping: Record<string, string> = {};

  // 处理顶级菜单及其子菜单
  menuList.forEach((menu) => {
    // 处理Layout布局的一级菜单
    if (menu.component === 'Layout') {
      // 已有子菜单的处理
      if (menu.children && menu.children.length > 0) {
        menu.children.forEach(child => {
          try {
          // 构建子路由的完整路径
          // 确保路径格式正确，去除多余的斜杠
          const parentPath = menu.path.endsWith('/') ? menu.path.slice(0, -1) : menu.path;
          const childPath = child.path.startsWith('/') ? child.path.slice(1) : child.path;
          const fullPath = `${parentPath}/${childPath}`.replace(/\/\//g, '/');
          
          console.log(`注册子路由: ${fullPath}, 名称: ${child.name}`);
          
          // 记录组件路径信息
          if (child.component) {
            routeComponentMapping[fullPath] = child.component;
          }
          
          // 构建路由配置
          const routeConfig = {
            // 这里关键是要设置正确的路径，是相对于父级AppLayout的路径
            // 不要包含/dashboard前缀
            path: fullPath.replace(/^\/dashboard/, ''),
            name: child.name,
            component: loadComponent(child.component, child.name),
            meta: { 
              ...child.meta, 
              requiresAuth: true, 
              parentPath: menu.path,
              parentTitle: menu.meta.title,
              fullPath: fullPath // 保存完整路径
            }
          }
          
            console.log(`实际注册的路由路径: ${routeConfig.path}, 名称: ${String(routeConfig.name)}`);
            
            // 解决同名路由问题：检查是否已存在同名但不同路径的路由
            const existingRoute = router.getRoutes().find(r => 
              String(r.name) === String(routeConfig.name) && 
              r.path !== routeConfig.path
            );
            
            if (existingRoute) {
              console.warn(`⚠️ 检测到同名但不同路径的路由: ${existingRoute.path} 和 ${routeConfig.path}, 名称: ${String(routeConfig.name)}`);
              
              // 为路由名称添加前缀，确保唯一性
              // 使用父级路径作为前缀，例如：system-operlog 替代 operlog
              const parentPrefix = menu.path.replace(/\//g, '').replace(/-/g, '');
              const uniqueName = `${parentPrefix}-${routeConfig.name}`;
              
              console.log(`为避免冲突，将路由名称从 "${routeConfig.name}" 修改为 "${uniqueName}"`);
              routeConfig.name = uniqueName;
            }
          
          // 注册路由
          router.addRoute('AppLayout', routeConfig as RouteRecordRaw)
            
            // 验证路由是否已正确注册
            const registeredRoute = router.getRoutes().find(r => 
              r.path === fullPath.replace(/^\/dashboard/, '/dashboard') || 
              r.path === routeConfig.path || 
              String(r.name) === String(routeConfig.name)
            );
            
            if (registeredRoute) {
              console.log(`✅ 路由已成功注册: ${registeredRoute.path}, 名称: ${String(registeredRoute.name || '')}`);
            } else {
              console.warn(`⚠️ 路由可能未成功注册: ${routeConfig.path}, 名称: ${String(routeConfig.name)}`);
            }
          } catch (error) {
            console.error(`注册子路由时出错:`, error);
          }
        })
      }
    } else if (menu.meta?.iframe) {
      // 收集iframe类型菜单
      iframeRoutes.push(menu)
    } else {
      try {
      // 处理非Layout的菜单
      console.log(`注册独立路由: ${menu.path}, 名称: ${menu.name}`);
      
      // 记录组件路径信息
      if (menu.component) {
        routeComponentMapping[menu.path] = menu.component;
      }
      
      // 构建路由配置，同样去除/dashboard前缀
      const routeConfig = {
        path: menu.path.replace(/^\/dashboard/, ''),
        name: menu.name,
        component: loadComponent(menu.component, menu.name),
        meta: { 
          ...menu.meta, 
          requiresAuth: true,
          fullPath: menu.path // 保存完整路径
        }
      }
      
        console.log(`实际注册的路由路径: ${routeConfig.path}, 名称: ${String(routeConfig.name)}`);
      
        // 解决同名路由问题：检查是否已存在同名但不同路径的路由
        const existingRoute = router.getRoutes().find(r => 
          String(r.name) === String(routeConfig.name) && 
          r.path !== routeConfig.path
        );
        
        if (existingRoute) {
          console.warn(`⚠️ 检测到同名但不同路径的路由: ${existingRoute.path} 和 ${routeConfig.path}, 名称: ${String(routeConfig.name)}`);
          
          // 为路由名称添加前缀，确保唯一性
          const pathPrefix = menu.path.split('/')[1] || '';
          const uniqueName = `${pathPrefix}-${routeConfig.name}`;
          
          console.log(`为避免冲突，将路由名称从 "${routeConfig.name}" 修改为 "${uniqueName}"`);
          routeConfig.name = uniqueName;
        }
        
        // 注册路由
      router.addRoute('AppLayout', routeConfig as RouteRecordRaw)
        
        // 验证路由是否已正确注册
        const registeredRoute = router.getRoutes().find(r => 
          r.path === menu.path.replace(/^\/dashboard/, '/dashboard') || 
          r.path === routeConfig.path || 
          String(r.name) === String(routeConfig.name)
        );
        
        if (registeredRoute) {
          console.log(`✅ 路由已成功注册: ${registeredRoute.path}, 名称: ${String(registeredRoute.name || '')}`);
        } else {
          console.warn(`⚠️ 路由可能未成功注册: ${routeConfig.path}, 名称: ${String(routeConfig.name)}`);
        }
      } catch (error) {
        console.error(`注册独立路由时出错:`, error);
      }
    }
  })

  // 保存iframe路由
  saveIframeRoutes(iframeRoutes)
  
  // 打印所有已注册的路由（标准化格式）
  console.log('%c ---------- 动态路由详细信息 ----------', 'background:#409EFF; color:white; padding: 4px; border-radius: 4px;');
  
  const allRoutes = router.getRoutes();
  console.log('所有路由配置:');
  
  // 根据routeComponentMapping构建一个反向映射，用于显示组件的实际路径
  const pathToComponentMap: Record<string, string> = {};
  Object.entries(routeComponentMapping).forEach(([routePath, componentPath]) => {
    pathToComponentMap[routePath] = componentPath;
  });
  
  // 保存注册的路由名称和对应的组件映射
  const componentMap = new Map();
   
  // 遍历所有动态加载的组件
  for (const [key, value] of Object.entries({...modules, ...componentModules})) {
    // 提取组件的文件路径（去掉 @/ 或 ../ 等前缀）
    const path = key.replace(/^(@\/|\.\.\/)+/, '').replace(/\.vue$/, '');
    componentMap.set(value, path);
  }
  
  // 获取组件实际路径的函数
  const getComponentPath = (comp: any) => {
    if (!comp) return 'null';
    if (typeof comp === 'function') {
      // 对于动态导入的组件，尝试找出路径
      for (const [importFn, path] of componentMap.entries()) {
        if (importFn === comp) {
          return `动态导入: ${path}`;
        }
      }
      
      // 如果在映射中找不到，尝试从函数字符串中提取路径
      const fnStr = comp.toString();
      if (fnStr.includes('import(')) {
        const matches = fnStr.match(/import\(['"]([^'"]+)['"]\)/);
        if (matches && matches[1]) {
          return `动态导入: ${matches[1]}`;
        }
      }
      
      return '动态导入组件（未能解析路径）';
    }
    return comp.name || '未命名组件';
  };
  
  console.log('%c ---------- 路由与组件对应关系 ----------', 'background:#67C23A; color:white; padding: 4px; border-radius: 4px;');
  Object.entries(pathToComponentMap).forEach(([routePath, componentPath]) => {
    console.log(`路由路径: ${routePath} -> 组件: ${componentPath}`);
  });
  
  allRoutes.forEach(route => {
    let componentInfo: any = '无组件';
    const routePath = route.path;
    
    // 尝试从映射中获取组件路径
    if (pathToComponentMap[routePath]) {
      // 添加前缀和后缀，显示完整的文件路径
      const componentPath = pathToComponentMap[routePath];
      // 判断是Layout特殊情况还是普通组件路径
      if (componentPath === 'Layout') {
        componentInfo = `组件: src/components/layout/AppLayout.vue`;
      } else {
        componentInfo = `组件路径: src/views/${componentPath}.vue`;
      }
    } else if (route.components) {
      componentInfo = {};
      for (const [name, comp] of Object.entries(route.components)) {
        componentInfo[name] = comp ? getComponentPath(comp) : 'null';
      }
    }
    
    console.log({
      path: route.path,
      name: route.name ? String(route.name) : 'null',
      meta: route.meta || {},
      component: componentInfo
    });
    
    // 如果有子路由，递归打印
    if (route.children && route.children.length > 0) {
      console.group('children:');
      route.children.forEach(child => {
        const childFullPath = `${route.path === '/' ? '' : route.path}/${child.path}`.replace(/\/\//g, '/');
        let childComponentInfo: any = '无组件';
        
        // 尝试从映射中获取子路由的组件路径
        if (pathToComponentMap[childFullPath]) {
          // 添加前缀和后缀，显示完整的文件路径
          const componentPath = pathToComponentMap[childFullPath];
          childComponentInfo = `组件路径: src/views/${componentPath}.vue`;
        } else if (child.components) {
          childComponentInfo = {};
          for (const [name, comp] of Object.entries(child.components)) {
            childComponentInfo[name] = comp ? getComponentPath(comp) : 'null';
          }
        } else {
          childComponentInfo = getComponentPath(child.component);
        }
        
        console.log({
          path: child.path,
          name: child.name ? String(child.name) : 'null',
          meta: child.meta || {},
          fullPath: childFullPath,
          component: childComponentInfo
        });
      });
      console.groupEnd();
    }
  });

  // 打印路由和实际组件路径的对照表
  console.log('%c ---------- 路由组件路径对照表 ----------', 'background:#67C23A; color:white; padding: 4px; border-radius: 4px;');
  console.log('后端配置的路由组件路径与实际文件路径对照:');
  Object.entries(routeComponentMapping).forEach(([routePath, componentPath]) => {
    // 跳过Layout组件
    if (componentPath === 'Layout') return;
    
    // 构建期望的完整文件路径
    const expectedFilePath = `src/views/${componentPath}.vue`;
    
    // 查找实际存在的文件路径
    let actualFilePath = '未找到匹配文件';
    
    // 尝试查找文件
    const possiblePaths = [
      `../../views/${componentPath}.vue`,
      `../../views/${componentPath}/index.vue`,
      `../../components/${componentPath}.vue`
    ];
    
    // 添加处理连字符的路径
    if (componentPath.includes('-')) {
      const pathParts = componentPath.split('/');
      const lastPart = pathParts[pathParts.length - 1];
      
      if (lastPart.includes('-')) {
        // 提取连字符前的部分作为目录名
        const dirName = lastPart.split('-')[0];
        const parentPath = pathParts.slice(0, -1).join('/');
        const convertedPath = parentPath ? `${parentPath}/${dirName}/index.vue` : `${dirName}/index.vue`;
        possiblePaths.push(`../views/${convertedPath}`);
      }
    }
    
    // 检查所有可能的路径
    for (const path of possiblePaths) {
      if (modules[path] || componentModules[path]) {
        actualFilePath = path.replace('../../', 'src/');
        break;
      }
    }
    
    // 打印对照信息
    console.log({
      路由: routePath,
      后端组件路径: componentPath,
      期望文件: expectedFilePath,
      实际文件: actualFilePath,
      匹配状态: expectedFilePath === actualFilePath ? '✅ 完全匹配' : 
               actualFilePath !== '未找到匹配文件' ? '⚠️ 找到类似文件' : '❌ 未找到文件',
    });
  });
}

// Only export loadComponent here, registerAsyncRoutes is already exported above
export { loadComponent }

// 在文件末尾添加全局调试函数
// 将模块和组件路径导出到全局变量，方便在控制台调试
if (typeof window !== 'undefined') {
  // @ts-ignore
  window.debugRouteModules = () => {
    console.clear();
    console.log('%c ---------- 动态路由组件路径调试工具 ----------', 'background:#409EFF; color:white; padding: 4px; border-radius: 4px;');
    
    // 打印所有可用的视图模块
    console.log('%c 可用的视图组件路径:', 'font-weight: bold; color: #409EFF;');
    const viewModules = Object.keys(modules).sort();
    console.log(`共有 ${viewModules.length} 个视图组件`);
    viewModules.forEach(path => console.log(`- ${path}`));
    
    // 打印所有可用的通用组件
    console.log('%c 可用的通用组件路径:', 'font-weight: bold; color: #409EFF;');
    const componentPaths = Object.keys(componentModules).sort();
    console.log(`共有 ${componentPaths.length} 个通用组件`);
    componentPaths.forEach(path => console.log(`- ${path}`));
    
    // 返回一些有用的工具函数
    return {
      testPath: (path: string) => {
        console.log(`测试路径: ${path}`);
        
        // 尝试各种组合
        const testPaths = [
          path,
          `../../views/${path}.vue`,
          `../../views/${path}/index.vue`,
          `../../components/${path}.vue`,
          `../../components/${path}/index.vue`
        ];
        
        // 处理可能的连字符路径
        if (path.includes('-')) {
          const pathParts = path.split('/');
          const lastPart = pathParts[pathParts.length - 1];
          
          if (lastPart.includes('-')) {
            // 提取连字符前的部分作为目录名
            const dirName = lastPart.split('-')[0];
            const parentPath = pathParts.slice(0, -1).join('/');
            const convertedPath = parentPath ? 
              `../../views/${parentPath}/${dirName}/index.vue` :
              `../../views/${dirName}/index.vue`;
            
            testPaths.push(convertedPath);
            console.log(`尝试连字符转换: ${path} -> ${convertedPath}`);
          }
        }
        
        testPaths.forEach(testPath => {
          // 检查模块是否存在，注意这里检查的是模块对象本身是否存在，而不是函数调用结果
          const moduleExists = Boolean(modules[testPath]);
          const componentExists = Boolean(componentModules[testPath]);
          const exists = moduleExists || componentExists;
          console.log(`${testPath}: ${exists ? '✅ 存在' : '❌ 不存在'}`);
        });
        
        return "测试完成";
      },
      
      // 帮助分析连字符路径
      analyzeHyphenPath: (path: string) => {
        console.log(`分析连字符路径: ${path}`);
        
        if (!path.includes('-')) {
          console.log('❌ 路径不包含连字符，无需分析');
          return;
        }
        
        const pathParts = path.split('/');
        const lastPart = pathParts[pathParts.length - 1];
        
        if (!lastPart.includes('-')) {
          console.log('❌ 最后部分不包含连字符，无法分析');
          return;
        }
        
        // 提取连字符前的部分作为目录名
        const dirName = lastPart.split('-')[0];
        const parentPath = pathParts.slice(0, -1).join('/');
        const convertedPath = parentPath ? 
          `${parentPath}/${dirName}` : 
          dirName;
          
        console.log('分析结果:');
        console.log(`- 原始路径: ${path}`);
        console.log(`- 父级路径: ${parentPath || '无'}`);
        console.log(`- 最后部分: ${lastPart}`);
        console.log(`- 提取目录: ${dirName}`);
        console.log(`- 转换路径: ${convertedPath}`);
        
        // 检查文件是否存在
        const fullPath = `@/views/${convertedPath}/index.vue`;
        const exists = Boolean(modules[fullPath]);
        console.log(`- 组件存在: ${exists ? '✅ 是' : '❌ 否'}`);
        
        return {
          originalPath: path,
          convertedPath: convertedPath,
          fullPath: fullPath,
          exists: exists
        };
      },
      
      modules,
      componentModules
    };
  };
} 